home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1990-05-03 | 10.2 KB | 388 lines |
- IMPLEMENTATION MODULE Debug; (* V#048 *)
-
- (* Erstellt Mai '87 von Thomas Tempelmann *)
-
- (*
- * G E M - V e r s i o n
- * =======================
- *
- * Gibt Modula-Zeilen aus, die erzeugt werden, wenn im Quelltext die
- * Compiler-Option "(*$D+*)" verwendet wird.
- *
- * Eine "Debug"-Ausgabeanweisung, die der Compiler erzeugt, hat folg. Format:
- *
- * ... normaler Maschinencode ...
- * TRAP #5 - Assembler-Anweisung, löst TRAP-5 Exception aus.
- * DC.W cmd - Kennung, die bestimmt, ob Zeile oder eine Zahl angezeigt
- * werden soll (siehe unten, Funktion 'dispLine').
- * [ ASC '...' ] - Modula-Text, falls eine Zeile angezeigt werden soll;
- * sonst steht die bestimmte Zahl auf dem Parameterstack.
- *)
-
- FROM SYSTEM IMPORT ADR, ADDRESS, ASSEMBLER, LONGWORD;
-
- FROM Excepts IMPORT InstallExc, ExcDesc;
-
- FROM PrgCtrl IMPORT TermProcess, CatchProcessTerm, TermCarrier;
-
- FROM Strings IMPORT Length, Empty;
-
- FROM MOSGlobals IMPORT UserBreak, MemArea;
-
- FROM SysTypes IMPORT ExcSet, TRAP5;
-
- FROM TextWindows IMPORT Read, Write, CondRead, ReadString, ForceMode,
- FlushKbd, WQualitySet, WindowQuality, Window, ShowMode;
-
- IMPORT TextWindows;
-
- FROM ModCtrl IMPORT GetModName;
-
- IMPORT StrConv;
-
- TYPE Mode = (m2Line, asmLine, procEntry, procExit);
-
- VAR WaitNext, WaitKey: BOOLEAN;
-
- io: Window;
-
-
- PROCEDURE WriteString (REF s:ARRAY OF CHAR);
- BEGIN
- TextWindows.WriteString (io,s)
- END WriteString;
-
- PROCEDURE WriteLn;
- BEGIN
- TextWindows.WriteLn (io)
- END WriteLn;
-
- PROCEDURE WriteLHex (v:LONGWORD);
- BEGIN
- WriteString (StrConv.LHexToStr (v,9))
- END WriteLHex;
-
- PROCEDURE dispRegs (VAR info: ExcDesc);
- BEGIN
- WriteLn;
- WITH info DO
- WriteString ('D0:'); WriteLHex (regD0);
- WriteString (' D1:'); WriteLHex (regD1);
- WriteString (' D2:'); WriteLHex (regD2);
- WriteString (' D3:'); WriteLHex (regD3);
- WriteLn;
- WriteString ('D4:'); WriteLHex (regD4);
- WriteString (' D5:'); WriteLHex (regD5);
- WriteString (' D6:'); WriteLHex (regD6);
- WriteString (' D7:'); WriteLHex (regD7);
- WriteLn;
- WriteString ('A0:'); WriteLHex (regA0);
- WriteString (' A1:'); WriteLHex (regA1);
- WriteString (' A2:'); WriteLHex (regA2);
- WriteString (' A3:'); WriteLHex (regA3);
- WriteLn;
- WriteString ('A4:'); WriteLHex (regA4);
- WriteString (' A5:'); WriteLHex (regA5);
- WriteString (' A6:'); WriteLHex (regA6);
- WriteString (' A7:'); WriteLHex (regUSP);
- END
- END dispRegs;
-
-
- PROCEDURE dispLine (mode: Mode; VAR info: ExcDesc);
-
- VAR buffered: BOOLEAN; bufCh: CHAR;
-
- PROCEDURE KeyPress():BOOLEAN;
- BEGIN
- CondRead (bufCh,buffered);
- RETURN buffered
- END KeyPress;
-
- PROCEDURE GetKey (VAR ch:CHAR);
- BEGIN
- IF buffered THEN
- buffered:= FALSE;
- ch:= bufCh
- ELSE
- TextWindows.BusyRead (ch)
- END
- END GetKey;
-
- VAR ch:CHAR; s:ARRAY [0..9] OF CHAR; p:CARDINAL; done,ok:BOOLEAN;
- ps: POINTER TO ARRAY [0..160] OF CHAR;
- proc,name: ARRAY [0..39] OF CHAR; rel: LONGCARD;
-
- BEGIN (* dispLine *)
- IF WaitKey THEN
- IF ~Continuous OR KeyPress() THEN
- IF Active THEN TextWindows.Show (io) END;
- REPEAT
- GetKey (ch);
- IF TextWindows.WasClosed (io) THEN
- TextWindows.Hide (io);
- Active:= FALSE
- END;
- ok:= TRUE;
- CASE CAP (ch) OF
- 15C: Continuous:= TRUE| (* RETURN *)
- ' ': Continuous:= FALSE| (* SPACE *)
- 3C : TermProcess (UserBreak)| (* CTRL-C *)
- 'A': Step:= 0L; Active:= TRUE; Continuous:= FALSE|
- 'S': WriteString ('Step? '); ReadString (io,s); p:=0;
- Step:= StrConv.StrToLCard (s,p,done);
- IF done THEN
- Active:= FALSE; Continuous:= TRUE; TextWindows.Hide (io);
- END|
- 'L': LineAddr:= ~LineAddr; ok:= FALSE|
- 'H': Hex:= TRUE; ok:= FALSE|
- 'D': Hex:= FALSE; ok:= FALSE|
- 'R': dispRegs (info); ok:= FALSE|
- ELSE
- ok:= FALSE
- END
- UNTIL ok
- END
- END;
-
- IF WaitNext THEN FlushKbd; WaitKey:= TRUE; WaitNext:= FALSE END;
-
- IF Active THEN Step:= 0L END;
-
- IF Step # 0L THEN
- DEC (Step);
- IF Step = 0L THEN Active:= TRUE; Continuous:= FALSE END;
- END;
-
- ps:= info.regPC; (* PC hinter Zeilentext setzen *)
- INC (info.regPC,Length (ps^)+1);
- IF ODD (info.regPC) THEN INC (info.regPC) END;
-
- IF Active THEN (* Zeile anzeigen *)
- WriteLn;
- IF (mode = m2Line) OR (mode = asmLine) THEN
- WriteLn;
- IF LineAddr THEN
- WriteLHex (info.regPC);
- WriteString (': ');
- GetModName (info.regPC,name,rel,proc);
- WriteString (name);
- WriteString (' / ');
- IF ~Empty (proc) THEN
- WriteString (proc)
- ELSE
- WriteString (StrConv.LHexToStr (rel,5))
- END;
- WriteLn;
- END;
- IF ps^[0]=12C (* LF *) THEN INC (ps) END;
- WriteString (ps^);
- WriteLn;
- ELSE
- IF mode = procEntry THEN
- WriteString ('-> Enter ')
- ELSE
- WriteString ('<- Exit ')
- END;
- WriteString (ps^);
- END;
- END;
- END dispLine;
-
- PROCEDURE dispLC (VAR info:ExcDesc; VarPar: BOOLEAN);
- VAR p: POINTER TO LONGCARD;
- q: POINTER TO ADDRESS;
- BEGIN
- IF VarPar THEN
- q:= ADDRESS(info.regA3)-4L;
- p:= q^
- ELSE
- p:= ADDRESS(info.regA3)-4L
- END;
- IF Hex THEN
- WriteString (StrConv.LHexToStr (p^,0));
- ELSE
- WriteString (StrConv.CardToStr (p^,0));
- END;
- WriteString (' ')
- END dispLC;
-
- PROCEDURE dispLI (VAR info:ExcDesc; VarPar: BOOLEAN);
- VAR p: POINTER TO LONGINT;
- q: POINTER TO ADDRESS;
- BEGIN
- IF VarPar THEN
- q:= ADDRESS(info.regA3)-4L;
- p:= q^
- ELSE
- p:= ADDRESS(info.regA3)-4L
- END;
- IF Hex THEN
- WriteString (StrConv.LHexToStr (p^,0));
- ELSE
- WriteString (StrConv.IntToStr (p^,0));
- END;
- WriteString (' ')
- END dispLI;
-
- PROCEDURE dispCard (VAR info:ExcDesc; VarPar: BOOLEAN);
- VAR p: POINTER TO CARDINAL;
- q: POINTER TO ADDRESS;
- BEGIN
- IF VarPar THEN
- q:= ADDRESS(info.regA3)-4L;
- p:= q^
- ELSE
- p:= ADDRESS(info.regA3)-2L
- END;
- IF Hex THEN
- WriteString (StrConv.HexToStr (p^,0));
- ELSE
- WriteString (StrConv.CardToStr (p^,0));
- END;
- WriteString (' ')
- END dispCard;
-
- PROCEDURE dispInt (VAR info:ExcDesc; VarPar: BOOLEAN);
- VAR p: POINTER TO INTEGER;
- q: POINTER TO ADDRESS;
- BEGIN
- IF VarPar THEN
- q:= ADDRESS(info.regA3)-4L;
- p:= q^
- ELSE
- p:= ADDRESS(info.regA3)-2L
- END;
- IF Hex THEN
- WriteString (StrConv.HexToStr (p^,0));
- ELSE
- WriteString (StrConv.IntToStr (p^,0));
- END;
- WriteString (' ')
- END dispInt;
-
- PROCEDURE dispChar (VAR info:ExcDesc; VarPar: BOOLEAN);
- VAR p: POINTER TO CHAR;
- q: POINTER TO ADDRESS;
- BEGIN
- IF VarPar THEN
- q:= ADDRESS(info.regA3)-4L;
- p:= q^
- ELSE
- p:= ADDRESS(info.regA3)-2L
- END;
- IF p^ < ' ' THEN (* Steuerzeichen als Oktalkonstante anzeigen *)
- WriteString (StrConv.NumToStr (ORD (p^),8,0,' '));
- Write (io,'C')
- ELSE
- Write (io,p^)
- END;
- WriteString (' ')
- END dispChar;
-
- PROCEDURE dispReal (VAR info:ExcDesc; VarPar: BOOLEAN);
- VAR p: POINTER TO LONGREAL;
- q: POINTER TO ADDRESS;
- BEGIN
- IF VarPar THEN
- q:= ADDRESS(info.regA3)-4L;
- p:= q^
- ELSE
- p:= ADDRESS(info.regA3)-8L
- END;
- WriteString (StrConv.RealToStr (p^,0,9));
- WriteString (' ')
- END dispReal;
-
- PROCEDURE dispBool (VAR info:ExcDesc; VarPar: BOOLEAN);
- VAR p: POINTER TO BOOLEAN;
- q: POINTER TO ADDRESS;
- BEGIN
- IF VarPar THEN
- q:= ADDRESS(info.regA3)-4L;
- p:= q^
- ELSE
- p:= ADDRESS(info.regA3)-2L
- END;
- IF p^ THEN
- WriteString ('TRUE ')
- ELSE
- WriteString ('FALSE')
- END;
- WriteString (' ')
- END dispBool;
-
-
- PROCEDURE HdlExc ( VAR info: ExcDesc ): BOOLEAN;
- VAR no:CARDINAL;
- BEGIN
- no:= CARDINAL (info.regPC^);
- INC (info.regPC,2);
- CASE no OF
- 0 : dispLine (m2Line, info)|
- 9 : dispLine (asmLine, info)|
- 20: dispLine (procEntry, info)|
- 21: dispLine (procExit, info)|
- ELSE
- IF Active THEN
- CASE no OF
- 1 : dispLC (info, FALSE)|
- 2 : dispLI (info, FALSE)|
- 3 : dispChar (info, FALSE)|
- 4 : dispBool (info, FALSE)|
- 5 : dispReal (info, FALSE)|
- 6 : dispCard (info, FALSE)|
- 7 : dispInt (info, FALSE)|
- 11 : dispLC (info, TRUE)|
- 12 : dispLI (info, TRUE)|
- 13 : dispChar (info, TRUE)|
- 14 : dispBool (info, TRUE)|
- 15 : dispReal (info, TRUE)|
- 16 : dispCard (info, TRUE)|
- 17 : dispInt (info, TRUE)|
- ELSE
- DEC (info.regPC,2);
- RETURN TRUE
- END
- END
- END;
- RETURN FALSE
- END HdlExc;
-
-
- VAR stk: ARRAY [1..2000] OF CARDINAL;
- wsp: MemArea;
- hdl: ADDRESS;
- tHdl: TermCarrier;
- ok: BOOLEAN;
-
- PROCEDURE Terminate;
- VAR ch:CHAR;
- BEGIN
- TextWindows.Show (io);
- WriteLn;
- WriteString ('Programmende: Bitte Taste...');
- Read (io,ch)
- END Terminate;
-
- BEGIN
- Active:= TRUE;
- Step:= 0L;
- Continuous:= FALSE;
- Hex := FALSE;
- LineAddr:= FALSE;
-
- (* damit erste Zeile sofort erscheint: *)
- WaitKey:= FALSE;
- WaitNext:= TRUE;
-
- TextWindows.Open (io, 70,100, WQualitySet{movable,closable,dynamic,titled},
- hideWdw, forceLine, ' Debugger ', -1,-1,-1,-1, ok);
-
- wsp.bottom:= ADR (stk);
- wsp.length:= SIZE (stk);
- InstallExc ( ExcSet{TRAP5}, HdlExc, wsp, hdl );
- IF hdl=NIL THEN HALT END;
- CatchProcessTerm (tHdl,Terminate,wsp);
- END Debug.
-